//======================================================================================
//  Apache License, Version 2.0
//  Notes:Use this command to anonymously check out the latest project source code:
//  Non-members may check out a read-only working copy anonymously over HTTP.
//  SVN checkout http://YHHLineCommandWsp.googlecode.com/svn/trunk/ 
//
//  Author:		Kevin Yang
//  Email:		Bigearrabbit@qq.com
//
//  DATE:		2013-4-6
//
//  File Name:	
//
//  Notes:
//
//======================================================================================

// Local  Framework
#include "YHHLineCommandCmd.h"
#include "YHHLineCommandDlg.h"       // needed to create an edition dialog box

//YHHLineCommandInterfaces Framework
#include "YHHILineCommandChild.h"         // needed to query the Line Command about its inputs ( edition mode )
#include "YHHILineCommandFactory.h"		  // needed to create a Line Command ( creation mode )

//YHHCatiaBaseUtlFrm Framework
#include "YHHCatiaBaseDefine.h"
#include "YHHVisualizationTools.h"

// ApplicationFrame Framework
#include "CATFrmEditor.h"                 // needed to retrieve the editor and then to highight objects

// Dialog Framework
#include "CATDlgDialog.h"                 // needed to return the dialog box to GiveMyPanel method of
// father class CATMMUiPanelStateCommand
// DialogEngine Framework
#include "CATFeatureImportAgent.h"        // needed to be able to pick any element whatever its context is
#include "CATStateActivateNotification.h" // to distinguish begin/resume state in the command activation
#include "CATDialogState.h"

// ObjectModelerBase Framework
#include "CATIContainer.h"                // needed to create a GS (Geometrical Set)

// ObjectSpecsModeler Framework
#include "CATISpecObject.h"               // needed to manage feature
#include "CATIDescendants.h"              // needed to aggregate the newly created Line Command

// InteractiveInterfaces
#include "CATIBuildPath.h"                // needed to build a path element to highlight a feature

// MechanicalModeler Framework
#include "CATIMechanicalRootFactory.h"    // needed to create a GS 
#include "CATIGSMTool.h"                  // GSMTool and HybridBody features
#include "CATIBasicTool.h"                // To retrieve the current tool
#include "CATIMmiGeometricalSet.h"        // Only for GSMTool feature
#include "CATIMmiNonOrderedGeometricalSet.h"  // Only for GS feature

// MechanicalModelerUI Framework
#include "CATPrtUpdateCom.h"              // needed to update the feature according to the user's update settings
#include "CATMmrLinearBodyServices.h"     // To insert in ordered and linear body

// MecModInterfaces Framework
#include "CATIPrtPart.h"                  // needed to look for a GSM tool
#include "CATMfBRepDefs.h"                // needed to declare the modes of BRep feature creation

// Visualization Framework
#include "CATPathElement.h"               // needed to highlight objects
#include "CATHSO.h"                       // needed to highlight objects    
#include "CATIVisProperties.h"            // needed to change Line Command's graphical appearance
#include "CATVisPropertiesValues.h"
#include "iostream.h"       

//System framework
#include "CATGetEnvValue.h"               // To define the type of development
#include "CATBoolean.h"
#include "CATLib.h"

// This command is used by a CATCommandheader
#include "CATCreateExternalObject.h" 


using namespace YHHLineCommand;//use YHHLineCommandChild NameSpace

CATCreateClass(YHHLineCommandCmd);


//-----------------------------------------------------------------------------
// YHHLineCommandCmd : constructor
// Deriving from CATMMUIPanelStateCmd provides an association between 
// the states of the command and the Ok/Cancel button.
//-----------------------------------------------------------------------------
YHHLineCommandCmd::YHHLineCommandCmd( YHHILineCommandChild *ipInstance):
CATMMUIPanelStateCmd("YHHLineCommandCommand")
,_pfiaStartPoint          (NULL)
,_pfiaLineDirection      (NULL)
,_pdaStartPoint    (NULL)
,_pdaLineDirection(NULL)
,_pdaValueChange(NULL)
,_InitialState      ( NULL ) 
,_piYHHILineCommand      ( NULL ) 
,m_pParamChild      ( NULL ) 
,m_pCore      ( NULL ) 
,_mode(YHHModeCreation)// creation mode
{
	//cout <<"YHHLineCommandCmd::YHHLineCommandCmd" << endl;

	//create m_pParamChild
	m_pParamChild = new YHHLineCommandChildParam();//create Default value Instance

	if ( ipInstance != NULL ) 
	{
		_mode = YHHModeEdit;// Edition mode.

		// Memorises what curve is being edited.
		_piYHHILineCommand = ipInstance;
		_piYHHILineCommand->AddRef();//Increments the reference count for the given interface. 

		// Reads the inputs of the Line Command.
		HRESULT rc= _piYHHILineCommand->GetParams(*m_pParamChild) ;
		//if ( FAILED(rc) ) 			return ; //do not check rc
	}
	// creates the dialog box
	_pMainDlg = new YHHLineCommandDlg();
	_pMainDlg->SetParamChildPtr(m_pParamChild);//Pass Value

	// builds the dialog box 
	// ! do not call panel->Build from the panel constructor
	_pMainDlg->Build();

	// To manage the highlight of the Line Command and the UI active object that 
	// is used to agregate the Line Command at the right place.
	_editor = CATFrmEditor::GetCurrentEditor();
	_HSO = NULL ;
	if ( NULL != _editor )
	{
		_HSO = _editor->GetHSO();
	}
	//core set
	m_pCore = new YHHLineCommandCore();//Core
	m_pCore->SetParamChildPtr(m_pParamChild);//pass value
	m_pCore->SetEditorPtr(_editor) ;//pass value
	m_pCore->SetCurrentElt(GetCurrentFeature());//pass value

}
//-----------------------------------------------------------------------------
YHHLineCommandCmd::~YHHLineCommandCmd()
{
	//cout <<"YHHLineCommandCmd::~YHHLineCommandCmd" << endl;

	// Releases member data pointers before leaving.
	YHHRequestDelayedDestructionIf(_pfiaStartPoint);//Destruction
	YHHRequestDelayedDestructionIf(_pfiaLineDirection);//Destruction
	YHHRequestDelayedDestructionIf(_pdaStartPoint);//Destruction
	YHHRequestDelayedDestructionIf(_pdaLineDirection);//Destruction
	YHHRequestDelayedDestructionIf(_pdaValueChange);//Destruction
	YHHRequestDelayedDestructionIf(_pMainDlg);//Destruction

	YHHDelete(m_pCore);//Release
	YHHDelete(m_pParamChild);//Delete Param
	_editor                = NULL ; //Set NULL Only
	_HSO                   = NULL ;//Set NULL Only
	_InitialState    = NULL ;//Set NULL Only
}
#pragma region VirtualFunction
//-----------------------------------------------------------------------------
void YHHLineCommandCmd::BuildGraph()
{
	// Agent Creation 
	_pfiaStartPoint  = new CATFeatureImportAgent ( "PointAgent"     , NULL , NULL , MfNoDuplicateFeature ) ;
	_pfiaLineDirection =  new CATFeatureImportAgent ( "DirectionAgent" , NULL , NULL , MfNoDuplicateFeature ) ; 
	_pdaStartPoint  = new CATDialogAgent    ( "StartPointActiveFieldAgent"    ) ;
	_pdaLineDirection= new CATDialogAgent  ( "LineDirectionActiveFieldAgent") ;
	_pdaValueChange= new CATDialogAgent  ( "ValueChangeAgent") ;

	//-----------------------------------------------------------------------------
	// Selection Agents
	//-----------------------------------------------------------------------------

	// _pfiaStartPoint to select a curve
	_pfiaStartPoint -> SetOrderedElementType ( "CATIMfZeroDimResult" );
	_pfiaStartPoint -> AddOrderedElementType ( "CATPoint"            );
	_pfiaStartPoint -> SetBehavior      ( CATDlgEngWithPrevaluation | CATDlgEngWithCSO     | CATDlgEngOneShot         );
	_pfiaStartPoint -> SetAgentBehavior ( MfPermanentBody           | MfLastFeatureSupport | MfRelimitedFeaturization );

	// _pfiaLineDirection to select a direction
	_pfiaLineDirection -> SetOrderedElementType ( "CATIMfLine" );
	_pfiaLineDirection -> AddOrderedElementType ( "CATLine"    );
	_pfiaLineDirection -> SetBehavior      ( CATDlgEngWithPrevaluation | CATDlgEngWithCSO );//|CATDlgEngOneShot);
	_pfiaLineDirection -> SetAgentBehavior ( MfPermanentBody           | MfLastFeatureSupport | MfRelimitedFeaturization );

	// Setting an ID to be able to read the created import
	GUID guid =  { /* c17e43d3-2b56-4753-bfe5-bb5f289e2091 */
		0xc17e43d3,
		0x2b56,
		0x4753,
		{0xbf, 0xe5, 0xbb, 0x5f, 0x28, 0x9e, 0x20, 0x91}
	};

	_pfiaLineDirection->SetImportApplicativeId(guid);
	CATDlgSelectorList* pField = _pMainDlg->GetField(FieldStartpoint );//get point list
	// _pCurveFieldAgent and _pDirectionFieldAgent to change current acquisition type
	_pdaStartPoint     -> AcceptOnNotify ( pField , pField->GetListSelectNotification() );

	pField = _pMainDlg->GetField(FieldLineDirection );//get point list
	_pdaLineDirection -> AcceptOnNotify ( pField , pField->GetListSelectNotification() );

	_pMainDlg->SetAcceptOnNotifyOfValueChange(_pdaValueChange);//add notify
	//-----------------------------------------------------------------------------
	// Command States
	//-----------------------------------------------------------------------------

	// Uses "PanelStates" instead of standard "DialogStates".
	// Theses states are provided by father class CATMMUIPanelStateCommand.
	// They make it possible for you not to worry about transition to OK and Cancel States.

	// _InitialState selection 
	_InitialState= GetInitialPanelState("InitialStateID");


	//Here to add update diaog code,maybe can avoid value change agent .Kevin Yang 2013-4-9
	_pMainDlg->UpdateDialog();	// Fills in the dialog panel fields.
	this->SetActiveField(FieldStartpoint);//set active field

	//add Agent
	_InitialState -> AddDialogAgent ( _pdaLineDirection ); 
	_InitialState -> AddDialogAgent ( _pdaStartPoint     ); 
	_InitialState -> AddDialogAgent ( _pdaValueChange ); 
	//-----------------------------------------------------------------------------
	// Transitions
	//-----------------------------------------------------------------------------

	// For Point Element ( click on several curves to change of curve )
	AddTransition ( _InitialState , _InitialState , 
		IsOutputSetCondition ( _pfiaStartPoint ) ,
		Action ( ( ActionMethod ) &YHHLineCommandCmd::ActionElemSelStartPoint ) );   

	// From Direction Element ( click on several directions to change of curve )
	AddTransition ( _InitialState , _InitialState , 
		IsOutputSetCondition ( _pfiaLineDirection ) ,
		Action ( (ActionMethod )& YHHLineCommandCmd::ActionElemSelLineDirection ) );   

	//for Point
	AddTransition ( _InitialState , _InitialState , 
		IsOutputSetCondition ( _pdaStartPoint ) ,
		Action ( ( ActionMethod ) &YHHLineCommandCmd::ActionFieldSelStartPoint ) );   

	// For Direction
	AddTransition ( _InitialState , _InitialState , 
		IsOutputSetCondition ( _pdaLineDirection ) ,
		Action ( (ActionMethod )& YHHLineCommandCmd::ActionFieldSelLineDirection ) );   
	
	// For Value Change
	AddTransition ( _InitialState , _InitialState , 
		IsOutputSetCondition ( _pdaValueChange ) ,
		Action ( (ActionMethod )& YHHLineCommandCmd::ActionValueChange ) );   
}
//-----------------------------------------------------------------------------
CATStatusChangeRC YHHLineCommandCmd::Activate (CATCommand * iCmd,
												   CATNotification * iNotif)
{
	cout <<" YHHLineCommandCmd::Activate" << endl; 

	// Sets the CC as the current feature 
	// only in edition mode and if the CC is inside an ordered body
	//
	if ( (NULL!= iNotif) && (0 == GetMode()) && (NULL !=_piYHHILineCommand) )
	{
		CATBoolean IsInsideOrderedBody = FALSE ;
		HRESULT rc = IsLineCommandInsideOrderedBody(IsInsideOrderedBody);
		if ( SUCCEEDED(rc) && (TRUE == IsInsideOrderedBody) )
		{
			// In case of first activation, SetLineCommandAsCurrentFeature will
			// keep the feature to restore at the end of the command

			if (((CATStateActivateNotification *) iNotif) -> GetType() 
				==  CATStateActivateNotification::Begin)
			{              
				// GetCurrentFeature is a method of CATMMUIStateCommand
				_spSpecObjOnPreviousCurrentFeat = GetCurrentFeature();
			}

			CATISpecObject * pSpecObjectOnLineCommand = NULL ;
			rc = _piYHHILineCommand->QueryInterface(IID_CATISpecObject,
				(void**) &pSpecObjectOnLineCommand);
			if (SUCCEEDED(rc))
			{
				// Sets the CC as current - method of CATMMUIStateCommand
				SetCurrentFeature(pSpecObjectOnLineCommand);

				pSpecObjectOnLineCommand->Release();
				pSpecObjectOnLineCommand = NULL ;
			}
		}

	}
	return (CATStatusChangeRCCompleted) ;
}
//-----------------------------------------------------------------------------
CATStatusChangeRC YHHLineCommandCmd::Cancel (CATCommand * iCmd,
												 CATNotification * iNotif)
{
	cout <<" YHHLineCommandCmd::Cancel" << endl; 

	// Check if the CC is inside an ordered body
	CATBoolean IsInsideOrderedBody = FALSE ;
	HRESULT rc = IsLineCommandInsideOrderedBody(IsInsideOrderedBody);

	// Restores the old current feature in edition mode
	// and if the CC is inside an ordered body
	if ( (0 == GetMode()) && SUCCEEDED(rc) && (TRUE ==IsInsideOrderedBody) )
	{
		// method of CATMMUIStateCommand
		SetCurrentFeature(_spSpecObjOnPreviousCurrentFeat);     
	}

	// Set the newly CC as the current feature in creation mode
	// and if the CC is inside an ordered body
	if ( (1 == GetMode()) && SUCCEEDED(rc) && (NULL!=_piYHHILineCommand) 
		&& (TRUE ==IsInsideOrderedBody) ) 
	{
		CATISpecObject * pSpecObjectOnLineCommand = NULL ;
		rc = _piYHHILineCommand->QueryInterface(IID_CATISpecObject,
			(void**) &pSpecObjectOnLineCommand);
		if (SUCCEEDED(rc))
		{
			// Sets the CC as current - method of CATMMUIStateCommand
			SetCurrentFeature(pSpecObjectOnLineCommand);

			pSpecObjectOnLineCommand->Release();
			pSpecObjectOnLineCommand = NULL ;

		}
	}

	return CATMMUIPanelStateCmd::Cancel(iCmd,iNotif);

}
//-----------------------------------------------------------------------------
CATBoolean YHHLineCommandCmd::CancelAction(void *)
{
	// Unset Repeat mode  when cancel or close is clicked 
	if (_editor) _editor -> UnsetRepeatedCommand();
	return TRUE ; 
} 
//-----------------------------------------------------------------------------
CATStatusChangeRC YHHLineCommandCmd::Deactivate (CATCommand * iCmd,
													 CATNotification * iNotif)
{
	cout << " YHHLineCommandCmd::Deactivate" << endl; 

	// Restores the old current feature
	// only in edition mode and if the CC is inside an ordered body
	//
	if ( 0 == GetMode() )
	{
		CATBoolean IsInsideOrderedBody = FALSE ;
		HRESULT rc = IsLineCommandInsideOrderedBody(IsInsideOrderedBody);
		if ( SUCCEEDED(rc) && (TRUE == IsInsideOrderedBody) )
		{
			// method of CATMMUIStateCommand
			SetCurrentFeature(_spSpecObjOnPreviousCurrentFeat);
		}
	}

	return (CATStatusChangeRCCompleted) ;
}
//-----------------------------------------------------------------------------
int YHHLineCommandCmd::GetMode()
{
	// This very simple methods checks if the user is creating or editing the Line Command.
	// This data is used by father command CATMMUIPanelStateCommand and by CATPrtUpdateCom.
	// They both provide standard edition command behaviour :
	// for example, it is not possible to create a sick Line Command ( a Line Command generating an error )
	
	//YHHModeCreation 1	:Creation mode
	//YHHModeEdit 0		: edit mode 
	return _mode; 
}
//-----------------------------------------------------------------------------
CATDlgDialog* YHHLineCommandCmd::GiveMyPanel()
{
	// Used by father class CATMMUiPanelStateCommand to be notified of events
	// sent by the OK and CANCEl press button.
	return (_pMainDlg);
}
//-----------------------------------------------------------------------------
CATISpecObject_var YHHLineCommandCmd::GiveMyFeature()
{
	return _MyFeature;
}
//-----------------------------------------------------------------------------
CATBoolean YHHLineCommandCmd::OkAction(void *)
{  
	HRESULT rc = E_FAIL;

	// Empty SO
	EmptySO();

	_pMainDlg->UpdateInfos();//update param
	//Create mode
	rc = CreateElement();        

	//
	// 1- Queries the CATISpecObject interface to update the Line Command
	//
	CATISpecObject *piSpecOnLineCommand = NULL;

	if ( SUCCEEDED(rc) && (NULL != piSpecOnLineCommand) )
	{
	}

	//
	// 2- Updates
	//
	if ( SUCCEEDED(rc) && (NULL != piSpecOnLineCommand ) )
	{
		// Uses CATPrtUpdateCom to update the Line Command ( manual update mode )
		// or the whole part ( automatic update mode ).
		// CATPrtUpdateCom also encapsulates interactive error management ( edit / delete, etc...)

		// piSpecOnLineCommand= the feature to update, translated into part->update 
		// in case of automatic update
		// 1= respects update interactive setting ( manual / automatic ) setting
		// GetMode= creation or modification. Prevents the user from creating a feature in error
		//
		CATPrtUpdateCom *pUpdateCommand =  new CATPrtUpdateCom ( piSpecOnLineCommand ,  
			1                    ,  
			GetMode()            ); 
	}

	//
	// 3- Inserts if necessary ( if inside an ordered (and linear) body )
	//
	if (SUCCEEDED(rc) && (NULL != piSpecOnLineCommand ) )
	{
		CATBoolean IsInsideOrderedBody = FALSE ;
		rc = IsLineCommandInsideOrderedBody(IsInsideOrderedBody);
		if ( SUCCEEDED(rc) && (TRUE == IsInsideOrderedBody) )
		{
			// Invoke the Insert method is mandatory
			// 
			CATBaseUnknown_var spBUOnCC = piSpecOnLineCommand ;
			rc = CATMmrLinearBodyServices::Insert(spBUOnCC);
		}
	}

	//
	// 4- Let's give our Line Command a better appearance
	//
	if ( SUCCEEDED(rc) && (1 == GetMode()) && (NULL != piSpecOnLineCommand ))
	{
		CATIVisProperties *piGraphPropOnLineCommand = NULL;
		rc = piSpecOnLineCommand->QueryInterface( IID_CATIVisProperties, 
			(void**)& piGraphPropOnLineCommand);
		if ( SUCCEEDED(rc) ) 
		{
			CATVisPropertiesValues Attribut;
			Attribut.SetColor(255, 255, 0); // yellow
			Attribut.SetWidth(4);           // medium thickness
			piGraphPropOnLineCommand->SetPropertiesAtt(Attribut, CATVPAllPropertyType, CATVPLine);

			piGraphPropOnLineCommand->Release();
			piGraphPropOnLineCommand = NULL ;
		}
	}

	if ( NULL != piSpecOnLineCommand )
	{
		piSpecOnLineCommand->Release(); 
		piSpecOnLineCommand = NULL ;
	}

	if ( SUCCEEDED(rc) )
		return TRUE;
	else
		return FALSE;
}
//-----------------------------------------------------------------------------
CATBoolean YHHLineCommandCmd::PreviewAction(void *)
{
	cout <<" YHHLineCommandCmd::PreviewAction:" << endl;// Preview
	 
	//your preview code here

	AfterValueChange();//action after value change
	return TRUE ; 
} 
#pragma endregion VirtualFunction
//-----------------------------------------------------------------------------
CATBoolean YHHLineCommandCmd::ActionElemSelLineDirection(void*)
{
	// checks if the selected object must be added ( not  selected yet ) or removed ( already selected ) as input direction
	AfterElementSelected(_pfiaLineDirection);  

	// gets ready for next acquisition
	_pfiaLineDirection->InitializeAcquisition();

	return TRUE;
}
//-----------------------------------------------------------------------------
CATBoolean YHHLineCommandCmd::ActionElemSelStartPoint(void*)
{

	// checks if the selected object must be added ( not  selected yet ) or removed ( already selected ) as input curve
	AfterElementSelected(_pfiaStartPoint);  

	// gets ready for next acquisition
	_pfiaStartPoint->InitializeAcquisition();

	return TRUE;
}
//-----------------------------------------------------------------------------
CATBoolean YHHLineCommandCmd::ActionFieldSelLineDirection(void*)
{
	// put the focus on the second field of the Line Command edition dialog box
	// ( Line direction ) and highlight the corresponding geometrical element 
	SetActiveField(FieldLineDirection);

	// gets ready for next acquisition
	_pdaLineDirection->InitializeAcquisition();

	return TRUE;
}
//-----------------------------------------------------------------------------
CATBoolean YHHLineCommandCmd::ActionFieldSelStartPoint(void*)
{
	// put the focus on the first field of the Line Command edition dialog box 
	// ( Start Point ) and highlight the corresponding geometrical element 
	SetActiveField(FieldStartpoint);

	// gets ready for next acquisition
	_pdaStartPoint->InitializeAcquisition();
	return TRUE;
}
//-----------------------------------------------------------------------------
CATBoolean YHHLineCommandCmd::ActionValueChange(void*)
{
	//add your code here

	
	// gets ready for next acquisition
	_pdaValueChange->InitializeAcquisition();

	this->AfterValueChange();//action after value change
	return TRUE;
}
//-----------------------------------------------------------------------------
void YHHLineCommandCmd::AfterElementSelected(CATFeatureImportAgent *ipAgent)
{
	YHHLineCommandField activeField = _pMainDlg->GetActiveField();
	cout <<" YHHLineCommandCmd::AfterElementSelected:" << activeField << endl;

	if ( (ipAgent == NULL) || (activeField == FieldNone) )
		return;

	// translates the selection into the good pointer on a CATBaseUnknwon model element
	CATBaseUnknown *pSelection = ipAgent->GetElementValue(ipAgent->GetValue());

	if ( NULL == pSelection ) return;//no input

	// gets a pointer on CATISpecObject for this element
	CATISpecObject *piSpecOnSelection = NULL;
	HRESULT rc = pSelection->QueryInterface(IID_CATISpecObject, (void**)&piSpecOnSelection);
	CATISpecObject_var spiSpecOnSelection = piSpecOnSelection;
	if ( FAILED(rc) || NULL_var == spiSpecOnSelection ) return;
	YHHRelease(piSpecOnSelection);//release


	// checks whether the selected element is the same than the one "in" the active field
	// o if this element is the same, the user wants to erase his selection.
	// o otherwise, the user wants to replace the old selected element by the new one.
	switch ( activeField )
	{
	case FieldStartpoint :
		{ 
			if ( m_pParamChild->StartPoint != spiSpecOnSelection) // not same one
			{
				m_pParamChild->StartPoint = spiSpecOnSelection; // other one, replaces the selection
			}

			this->SetActiveField(FieldLineDirection);//change to FieldLineDirection

			break;
		}          
	case FieldLineDirection :
		{ 
			if ( m_pParamChild->LineDirection != spiSpecOnSelection) // not same one
			{
				m_pParamChild->LineDirection = spiSpecOnSelection; // other one, replaces the selection
			}

			this->SetActiveField(FieldStartpoint);//change to FieldStartpoint

			break;
		}
	default:
		return;//no action
	}//switch

	AfterValueChange();//action after value change

	return;
}    
//-----------------------------------------------------------------------------
void YHHLineCommandCmd::AfterValueChange()
{
	cout <<" YHHLineCommandCmd::AfterValueChange:" << endl;

	_pMainDlg->UpdateInfos();//refreash infor

	//if exist instance
	if (_piYHHILineCommand)
	{
		_piYHHILineCommand->SetParams(*m_pParamChild);//set param
	}
	//your other code here
	
	_pMainDlg->UpdateDialog();// updates all the param to the panel 

	return;
}       
//-----------------------------------------------------------------------------
HRESULT YHHLineCommandCmd::CreateElement()
{
	cout <<" YHHLineCommandCmd::CreateElement" << endl;

	if (NULL == m_pCore) return E_INVALIDARG;
	m_pCore->Create();//create
	_MyFeature = m_pCore->GetMyFeature();//get my feature;
	return S_OK ;
}
//-----------------------------------------------------------------------------
void YHHLineCommandCmd::fiaAgentClear()
{
	_InitialState->RemoveDialogAgent(_pfiaStartPoint);//remove Agent
	_InitialState->RemoveDialogAgent(_pfiaLineDirection);//remove Agent
}
//-----------------------------------------------------------------------------
void YHHLineCommandCmd::fiaAgentUpdate()
{
	YHHLineCommandField    activeField = _pMainDlg->GetActiveField();//get active Field

	fiaAgentClear();//clear first
	//swith the field number
	switch (activeField )
	{
	case FieldStartpoint : 
		{
			_InitialState->AddDialogAgent(_pfiaStartPoint);
			_InitialState->SetMessage("Please Select the Start Point Element or Another Field.");
			return; 
		}
	case FieldLineDirection :
		{
			_InitialState->AddDialogAgent(_pfiaLineDirection);
			_InitialState->SetMessage("Please Select the Line Direction Element or Another Field.");
			return; 
		}

	default:
		_InitialState->SetMessage("None Element can select. Please Focus on a Field.");
	}
}
//-----------------------------------------------------------------------------
HRESULT YHHLineCommandCmd::IsLineCommandInsideOrderedBody(CATBoolean & oIsInsideOrderedBody )
{
	//
	// returns TRUE if the CC is inside an ordered body
	// otherwise FALSE 
	//
	HRESULT rc = E_FAIL ;

	oIsInsideOrderedBody = FALSE ;

	if ( NULL_var != _MyFeature )
	{
		CATISpecObject * pSpecObjectOnLineCommand = NULL ;
		rc = _MyFeature->QueryInterface(IID_CATISpecObject,
			(void**) &pSpecObjectOnLineCommand);
		if ( SUCCEEDED(rc) )
		{ 
			// Retrieve the father of the CC 
			CATISpecObject * pFatherCC = NULL ;
			pFatherCC = pSpecObjectOnLineCommand->GetFather();
			if ( NULL != pFatherCC )
			{
				// The father must be a GSMTool or an HybridBody
				CATIGSMTool *piGSMToolFatherCC = NULL;
				rc = pFatherCC->QueryInterface ( IID_CATIGSMTool, (void**) &piGSMToolFatherCC);
				if ( SUCCEEDED(rc) )
				{
					// The father can be a ordered or not
					int IsAnOrderedBody = -1 ;
					piGSMToolFatherCC->GetType(IsAnOrderedBody) ;
					if ( 1 == IsAnOrderedBody )
					{
						oIsInsideOrderedBody = TRUE ;
					} 

					piGSMToolFatherCC->Release();
					piGSMToolFatherCC = NULL ;
				}

				pFatherCC->Release();
				pFatherCC = NULL ;
			}else rc = E_FAIL ;

			pSpecObjectOnLineCommand->Release();
			pSpecObjectOnLineCommand = NULL ;
		}
	}

	return rc ;

}
//-----------------------------------------------------------------------------
void YHHLineCommandCmd::SetActiveField(YHHLineCommandField iActiveField)
{

	// this method main goal is to show the user that the acquisition
	// is now dedicated to the input field
	_pMainDlg->SetActiveField(iActiveField); // puts the focus on the Active Field is the Line Command edition dialog box
	_pMainDlg->SetActiveFieldFocus(); // Focus

	// first let's empty current highlighted objects
	if ( NULL != _HSO )_HSO->Empty(); 

	//Field type switch
	switch(iActiveField)
	{
	case FieldStartpoint://Startpoint
		YHH::HSOAppend(m_pParamChild->StartPoint, _editor, _HSO);//append to hso
		break;
	case FieldLineDirection://LineDirection
		YHH::HSOAppend(m_pParamChild->LineDirection, _editor, _HSO);//append to hso
		break;
	}

	fiaAgentUpdate();//update the Agent
}
//---------------------------------------------------------
